import { MutableRefObject } from 'react';
import { extendApi } from '@inbiz/utils';
import { PageData, RecordType } from '../../interfaces';
import { ColumnConst, ConnectorEnum } from '../../shared';
import { SearchParamsProps } from '../../context';

// 1. dataSource: 传入参数时为设置数据， 没有传入时 为返回数据 当前页的数据
// 2. setSelect: (id, stauts) => boolean 设置当前页选中状态,取消选中状态，
//    设置成功返回true；当前页没有这条数据是设置失败 返false  设置了会触发onSelect事件
// 3. getRows 获取某一项的详情
// 4. getSelectedRowIndex 获取选中行的index
// 5. getSelectedIds 获取所有选中项的id
// 6. load(param) 主动请求接口渲染数据 参数为自定义查询参数，参数中存在分页数时，以当前参数分页为准，不存在时为默认分页参数

type queryParam = {
  current: string;
  pageSize: string;
};
type pageData = {
  data: { [key: string]: any }[];
  total: number;
  primary: string;
};
type param = {
  pageInfo: {
    current: number | string;
    pageSize: number | string;
  };
  conditions: { [key: string]: any }[];
  iConditions?: { [key: string]: any };
};
interface IProps {
  modelname: string;
  searchRef: MutableRefObject<SearchParamsProps>;
  modalFormRef: MutableRefObject<any>;
  tableCacheRef: MutableRefObject<any>;
  modalRef: MutableRefObject<any>;
  selectedRowKeys: number[];
  rest: any;
  primaryKey: string;
  pageData: PageData;
  setSelectedRowKeys: (keys: any[]) => void;
  setQueryParam: (param: queryParam) => void;
  setPageData: (data: pageData | Function) => void;
  fetchData: (data: param, triggerMode?: 'outside' | 'inside') => void;
  dispatch: (param: any) => void;
}

interface ITriggerOperation {
  actionType: 'add' | 'del' | 'recovery' | 'thoroughDel' | 'import' | 'export' | 'print' | 'custom';
  windowName: string;
  openMode: 'modal' | 'top' | 'bottom' | 'left' | 'right';
}

export default extendApi((_events: MutableRefObject<any>, props: IProps) => {
  const {
    modelname,
    searchRef,
    modalFormRef,
    tableCacheRef,
    modalRef,
    selectedRowKeys,
    rest,
    primaryKey,
    pageData,
    setSelectedRowKeys,
    setQueryParam,
    setPageData,
    fetchData,
    dispatch,
    inbiz,
    controlId
  } = props;
  return {
    setSelect: (ids: number | number[], isSelected: boolean = true) => {
      const keys = Array.isArray(ids) ? ids : [ids];
      if (!keys?.length) {
        setSelectedRowKeys([])
        return;
      }
      if (isSelected) {
        setSelectedRowKeys([...new Set([...selectedRowKeys, ...keys])]);
      } else {
        let newKeys: number[] = [...selectedRowKeys];
        keys.forEach((key) => {
          const index = newKeys.findIndex((item) => item === key);
          if (index != -1) {
            newKeys.splice(index, 1);
          }
        });
        setSelectedRowKeys(newKeys);
      }
    },
    setParams: (params: any[]) => {
      let initParams = Array.isArray(params) ? params : [params];
      if (initParams?.length > 0) {
        (initParams = initParams.map((item) => {
          if (Boolean(item?.modelName)) {
            return item;
          } else {
            return {
              ...item,
              modelName: modelname,
            };
          }
        })),
          (searchRef.current.initParams = initParams);
      } else {
        searchRef.current.initParams = [];
      }
    },
    setPageInfo: (val: { [key: string]: any }) => {
      if (!modalFormRef) {
        return
      }
      modalFormRef.current = val;
    },
    getParams: (isAll?: boolean) => {
      if (isAll) {
        return searchRef.current
      }
      return searchRef.current.initParams;
    },
    load: (param: any) => {
      const pageSize = searchRef.current.pageInfo!.pageSize;
      const { id, index = 1, size = pageSize, conditions = [], iConditions = {} } = param || {};
      let cacheConditions = [...conditions];
      tableCacheRef.current.relationParent = param?.id;
      if (param) {
        if (id) {
          if (conditions?.length) {
            cacheConditions[0].condition.unshift({
              connector: 'and',
              field: rest.relationField,
              modelName: rest.modelname,
              operator: 'eq',
              value: id,
            });
          } else {
            cacheConditions = [
              {
                connector: ConnectorEnum.and,
                index: 0,
                condition: [
                  {
                    connector: 'and',
                    field: rest.relationField,
                    modelName: rest.modelname,
                    operator: 'eq',
                    value: param.id,
                  },
                ],
              },
            ];
          }
        }
        fetchData(
          {
            pageInfo: {
              current: index,
              pageSize: size || searchRef.current.pageInfo!.pageSize,
            },
            conditions: cacheConditions,
            iConditions,
          },
          'outside'
        );
      } else {
        let conditions: any[] = [];
        if (searchRef.current.initParams && searchRef.current.initParams.length > 0) {
          conditions = [
            {
              index: 0,
              connector: 'and',
              condition: searchRef.current.initParams.map((item) => {
                if (Boolean(item?.modelName)) {
                  return item;
                } else {
                  return {
                    ...item,
                    modelName: modelname,
                  };
                }
              }),
            },
          ];
        }
        searchRef.current.conditions = conditions;
        fetchData(
          {
            pageInfo: {
              current: searchRef.current.pageInfo!.current,
              pageSize: searchRef.current.pageInfo!.pageSize,
            },
            conditions: conditions,
          },
          'outside'
        );
      }
      setSelectedRowKeys && setSelectedRowKeys([]);
      setQueryParam &&
        setQueryParam({
          current: param?.index || searchRef.current.pageInfo.current,
          pageSize: param?.size || searchRef.current.pageInfo.pageSize,
        });
      searchRef.current = {
        ...searchRef.current,
        pageInfo: {
          current: param?.index || searchRef.current.pageInfo.current,
          pageSize: param?.size || searchRef.current.pageInfo.pageSize,
        },
        conditions: param?.conditions || searchRef.current.conditions,
        iConditions: param?.iConditions || searchRef.current.iConditions,
      };
    },
    loadData: (data: any) => {
      setPageData((old) => ({
        data: data || [],
        total: data?.length || 0,
        primary: old.primary,
      }));
    },
    getData: () => {
      const pagedata = pageData?.data ?? []
      return [...pagedata];
    },
    getRows: () => {
      const pagedata = pageData?.data ?? []
      return [...pagedata];
    },
    getSelectedIds: () => {
      return selectedRowKeys;
    },
    getSelectedRowIndex: () => {
      const data: any = [];
      selectedRowKeys.forEach((key) => {
        const cache = pageData.data?.find((item) => item[primaryKey] === key);
        if (cache) {
          data.push({ ...cache });
        }
      });
      return data?.reduce((buf: number[], row: RecordType) => {
        buf.push(row[ColumnConst.index]);
        return buf;
      }, []);
    },
    getSelectedRow: () => {
      const data: any = [];
      selectedRowKeys.forEach((key) => {
        const cache = pageData.data?.find((item) => item[primaryKey] === key);
        if (cache) {
          data.push({ ...cache });
        }
      });
      return data.length > 0 ? data : null;
    },
    getClickRow: () => {
      return tableCacheRef.current.clickRowData;
    },
    getPrimaryKey: () => {
      return primaryKey;
    },
    openModal: (param: any) => {
      modalRef.current.showModal(true, param);
    },
    closeModal: () => {
      modalRef.current.showModal(false);
    },
    triggerOperation: (param: ITriggerOperation) => {
      dispatch({ ...param });
    },
    setBtnDisabled: (operationflag:string, disabled: boolean) => {
      const options = inbiz(controlId)?.columnConfig?.tableValues?.actions?.find(item => item.operationflag === operationflag)
      if (options) {
        options.disabled = disabled
      }
    }
  };
});
